/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package InfoFicheros;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.ArrayList;

/**
 *
 * @author oscarsoto
 */
public class MetodosGenerales {

    /*
     
     Metodo utilizado para el envio de un fichero
	
     Recibe la ruta del fichero a enviar (String), y el OutPutStream para el envio
	
     Manda el fichero Byte a Byte
     
     */
    public static void enviarFichero(String nombreFichero, DataOutputStream salidaPrimitiva) throws Exception {
        //Definimos las variables
        byte[] buffer = new byte[2048];
        int in = 0;
        int mbPasados = 0;
        File fichero = new File(nombreFichero);

        FileInputStream leerFichero = new FileInputStream(fichero);
        salidaPrimitiva.writeInt((int) fichero.length()); //Enviamos el temaño del fichero

        while ((in = leerFichero.read(buffer)) != -1) { //Enviamos el fichero
            salidaPrimitiva.write(buffer, 0, in);
            mbPasados += in;

            System.out.println(mbPasados + " Bytes pasados de " + Long.toString(fichero.length()) + "Bytes"); //Mostramos los bytes que se estan pasando(Esto hay que utilizarlo para mostrar una barra en el entorno grafico).
        }

        leerFichero.close(); //Cerramos el fichero
    }

    /*
     
     Metodo utilizado para la recepcion de un fichero
	
     Recibe la ruta del fichero a recibir (String), y el DataInputStream para la recepcion
	
     Recibe el fichero Byte a Byte
     
     */
    public static void recibirFichero(String direccionFichero, DataInputStream entradaPrimitiva) throws Exception {
        //Definimos las variables
        File ficheroEscribir = new File(direccionFichero);
        FileOutputStream escribirFichero = new FileOutputStream(ficheroEscribir);

        int in;
        byte[] buffer = new byte[2048];
        int tammanoFichero = entradaPrimitiva.readInt(); //Recibimos el tamaño total del fichero
        int tammanoFicheroSuma = 0;

        System.out.println("Recibiendo fichero");

        while ((in = entradaPrimitiva.read(buffer)) != -1) { //Recibimos el fichero y lo volcamos en un fichero local
            escribirFichero.write(buffer, 0, in);

            tammanoFicheroSuma += in; //Vamos sumando los bytes que nos llegan 
            System.out.println(convertirTammano((double) tammanoFicheroSuma) + " pasados de " + convertirTammano((double) tammanoFichero)); //Mostramos los bytes que se estan pasando(Esto hay que utilizarlo para mostrar una barra en el entorno grafico).
            if (tammanoFicheroSuma == tammanoFichero) { //Si los bytes que nos han llegados son los mismos que tiene en total el fichero, nos salimos del bucle.
                break;
            }
        }

        escribirFichero.close(); //Cerramos el fichero

    }

    /*
     
     Metodo utilizado para el envio de carpetas
	
     Recibe la ruta del fichero a recibir (String), y el DataOnputStream para el envio, y la barra del sistema
	
     Envia los ficheros Byte a Byte, si la carpeta contiene otra, se llamara asi mismo de forma recursiva.
     
     */
    public static void enviarCarpeta(String nombreCarpeta, String nuevaDireccion, DataOutputStream salidaPrimitiva) throws Exception {
        String BARRA_SISTEMA_ANDROID = "/";
        Path path;
                
        File carpeta = new File(nombreCarpeta);
        String nuevaCarpeta = nuevaDireccion + BARRA_SISTEMA_ANDROID + carpeta.getName();

        salidaPrimitiva.writeUTF("MKDIR:" + nuevaCarpeta); //Enviamos la orden de crear una nueva carpeta 

        File ficherosCarpeta[] = carpeta.listFiles();

        for (File fichero : ficherosCarpeta) { //Listamos los ficheros contenidos en la carpeta

            if (!fichero.isDirectory()) { //Si es un fichero lo enviamos
                path = Paths.get(nombreCarpeta);
                String direccionFichero = path.resolve(fichero.getName()).toString();
                String nuevoDirectorioFichero = nuevaCarpeta + BARRA_SISTEMA_ANDROID + fichero.getName();

                System.out.println(direccionFichero);
                System.out.println(nuevoDirectorioFichero);

                String mensaje = "PUT:" + nuevoDirectorioFichero;

                salidaPrimitiva.writeUTF(mensaje);

                enviarFichero(direccionFichero, salidaPrimitiva);

                Thread.sleep(1500); //Dormimos el metodo, entre envio y envio, para que no tener errores en el envio

            } else { //Si es una carpeta volvemos a llamar a este metodo de manera recursiva

                System.out.println("Subcarpeta");
                path = Paths.get(nombreCarpeta);
                String direccionCarpeta = path.resolve(fichero.getName()).toString();

                System.out.println(direccionCarpeta);

                enviarCarpeta(direccionCarpeta, nuevaCarpeta, salidaPrimitiva);
            }
        }
    }

    /*
     
     Metodo utilizado para el almacenamiento de los ficheros contenidos en un directorio
	
     Recibe los ficheros contenidos en un directorio (.listFiles())
	
     Devuelve un ArrayList con los ficheros 
     
     */
    public static ArrayList<InfoFicheros> listarDirectorio(File[] directorio) {
        ArrayList<InfoFicheros> listaFicheros = new ArrayList<InfoFicheros>();
        InfoFicheros fichList = new InfoFicheros();

        for (File fichero : directorio) {

            fichList.setRutaDirectorioContenido(fichero.getParentFile().getAbsolutePath());
            fichList.setNombre(fichero.getName());
            if (fichero.isDirectory()) {
                fichList.setTipo("Directorio");
            } else if (fichero.isFile()) {
                fichList.setTipo("Fichero");
                fichList.setTamanno(Long.toString(fichero.length()));
            } else {
                fichList.setTipo("No Reconocido");
            }

            fichList.setUltimaFecha(saberFechaHora(new Date(fichero.lastModified())));
            listaFicheros.add(fichList);
            fichList = new InfoFicheros();
        }

        return listaFicheros;
    }

    /*
      
     Convertimos el tamaño en bytes en un tamaño mas legible (Bytes, Kb, Mb, Gb)
     
     Tipo de Entrada Double
     
     Tipo de Salida String
     
     */
    public static String convertirTammano(double division) {
        String tipo;

        if (division >= 1024) { //Dividimos para conseguir la unidad de almacenamiento adecuada
            division /= 1024;
            if (division >= 1024) {
                division /= 1024;
                if (division >= 1024) {
                    division /= 1024;
                    tipo = "Gb";
                } else {
                    tipo = "Mb";
                }
            } else {
                tipo = "Kb";
            }
        } else {
            tipo = "Bytes";
        }

        double redondeo = Math.round(division * 100.0) / 100.0; //Redondeamos el resultado a 4 digitos
        return Double.toString(redondeo) + " " + tipo; //Restornamos el resultado con su unidad de almacenamiento
    }

    /*
      
     Damos estilo y transformamos a String la fecha dada por un Fichero
     
     Tipo de Entrada Date
     
     Tipo de Salida String
     
     */
    public static String saberFechaHora(Date d) {
        Calendar c = new GregorianCalendar();
        c.setTime(d);

        //Transformamos el dia a String si es menor que 10 le ponemos un 0 delante
        String dia = Integer.toString(c.get(Calendar.DATE));
        if (dia.length() == 1) {
            dia = "0" + dia;
        }

        //Transformamos el mes a String si es menor que 10 le ponemos un 0 delante
        String mes = Integer.toString(c.get(Calendar.MONTH));
        if (mes.length() == 1) {
            mes = "0" + mes;
        }

        //Transformamos el annio y la hora en String
        String annio = Integer.toString(c.get(Calendar.YEAR));
        String hora = Integer.toString(c.get(Calendar.HOUR_OF_DAY));
        String minuto = Integer.toString(c.get(Calendar.MINUTE));
        String segundo = Integer.toString(c.get(Calendar.SECOND));

        //Definimos el estilo de la fecha y la devolvemos
        return dia + "/" + mes + "/" + annio + " " + hora + ":" + minuto + ":" + segundo;
    }

     /*
      
     Devolvemos la barra utilizada por el sistema dependiendo si es Windows o sistema Unix
     
     Tipo de Salida String
     
     */
    public static String definirSistema() {
        String barra = "";
        String sistemaOperativo = System.getProperty("os.name"); //Obtemos el nombre del sistema operativo

        if (sistemaOperativo.contains("Windows")) { //Miramos si es Windows o sistema Unix y definimos la barra
            barra = "\\";
        } else {
            barra = "/";
        }
        
        return barra;
    }
}